home *** CD-ROM | disk | FTP | other *** search
- /* ================================================================== *
- * Editor mined *
- * Operating system dependant I/O *
- * ================================================================== */
-
- #include "mined.h"
- #include <errno.h>
- #include <signal.h>
-
- #ifdef CURSES
- #include <curses.h>
- #undef FALSE
- #undef TRUE
- #undef TERMIO /* \ must be */
- #undef SGTTY /* / disabled */
- #endif
-
- #ifdef TERMIO
- #include <termios.h>
- #endif
- #ifdef SGTTY
- #include <sys/ioctl.h> /* <sgtty.h> ? */
- extern void ioctl ();
- #endif
-
- #ifdef SIGPHONE /* this trick was taken from less' screen.c */
- #include <sys/window.h> /* for window size detection */
- #endif
-
- #ifdef msdos
- #define _getch_
- #include <dos.h>
- #endif
-
- #ifdef unix
- #include <sys/time.h> /* for struct timeval (for select in inputreadyafter) */
- #define selectread /* use select () ? */
- #endif
-
- #ifdef vms
- #include <socket.h> /* for select () and struct timeval */
- # ifdef CURSES
- # define _getch_
- # endif
- #endif
-
- #ifdef _getch_
- #ifndef CURSES
- extern int getch ();
- #endif
- #endif
-
- /* ================================================================== *
- * Unix signalling routines *
- * ================================================================== */
-
- void
- catch_signals (catch)
- void (* catch) ();
- {
- #ifdef SIGHUP
- signal (SIGHUP, catch);
- #endif
- #ifdef SIGILL
- signal (SIGILL, catch);
- #endif
- #ifdef SIGTRAP
- signal (SIGTRAP, catch);
- #endif
- #ifdef SIGABRT
- signal (SIGABRT, catch);
- #endif
- #ifdef SIGEMT
- signal (SIGEMT, catch);
- #endif
- #ifdef SIGFPE
- signal (SIGFPE, catch);
- #endif
- #ifdef SIGBUS
- signal (SIGBUS, catch);
- #endif
- #ifdef SIGSEGV
- signal (SIGSEGV, catch);
- #endif
- #ifdef SIGSYS
- signal (SIGSYS, catch);
- #endif
- #ifdef SIGPIPE
- signal (SIGPIPE, catch);
- #endif
- #ifdef SIGALRM
- signal (SIGALRM, catch);
- #endif
- #ifdef SIGTERM
- signal (SIGTERM, catch);
- #endif
- #ifdef SIGXCPU
- signal (SIGXCPU, catch);
- #endif
- #ifdef SIGXFSZ
- signal (SIGXFSZ, catch);
- #endif
- #ifdef SIGVTALRM
- signal (SIGVTALRM, catch);
- #endif
- #ifdef SIGPROF
- signal (SIGPROF, catch);
- #endif
- #ifdef SIGLOST
- signal (SIGLOST, catch);
- #endif
- #ifdef SIGUSR1
- signal (SIGUSR1, catch);
- #endif
- #ifdef SIGUSR2
- signal (SIGUSR2, catch);
- #endif
- #ifdef SIGUSR3
- signal (SIGUSR3, catch);
- #endif
- }
-
- #ifdef SIGTSTP
- void
- suspendmyself ()
- {
- kill (getpid (), SIGTSTP);
- }
- FLAG cansuspendmyself = TRUE;
- #else
- void
- suspendmyself ()
- {}
- FLAG cansuspendmyself = FALSE;
- #endif
-
- #ifdef SIGWINCH
- /*
- * Catch the SIGWINCH signal sent to mined.
- */
- void
- catchwinch ()
- {
- winchg = TRUE;
- /* if (waitingforinput == TRUE) RDwin (); */
- /* This is now performed in __readchar () to prevent display garbage
- in case this interrupts occurs during display output operations which
- get screen size related values changed while relying on them. */
- signal (SIGWINCH, catchwinch); /* Re-installation of the signal */
- }
- #endif
-
- #ifdef SIGQUIT
- /*
- * Catch the SIGQUIT signal (^\) sent to mined. It turns on the quitflag.
- */
- void
- catchquit ()
- {
- #ifdef UNUSED /* Should not be needed with new __readchar () */
- /* Was previously needed on SUN but showed bad effects on Iris. */
- static char quitchar = '\0';
- if (waitingforinput == TRUE)
- /* simulate input to enable immediate break also during input */
- ioctl (input_fd, TIOCSTI, & quitchar);
- #endif
- quit = TRUE;
- signal (SIGQUIT, catchquit); /* Re-installation of the signal */
- }
- #endif
-
- #ifdef SIGBREAK
- /*
- * Catch the SIGBREAK signal (control-Break) and turn on the quitflag.
- */
- void
- catchbreak ()
- {
- quit = TRUE;
- signal (SIGBREAK, catchbreak); /* do we need this ? */
- }
- #else
- # ifdef msdos
- int
- controlbreak ()
- {
- quit = TRUE;
- return 1 /* continue program execution */;
- }
- # endif
- #endif
-
- #ifdef SIGINT
- /*
- * Catch the SIGINT signal (^C) sent if it cannot be ignored by tty driver
- */
- void
- catchint ()
- {
- intr_char = TRUE;
- signal (SIGINT, catchint); /* Re-installation of the signal */
- }
- #endif
-
- /* ================================================================== *
- * Terminal mode switcher *
- * ================================================================== */
-
- /*
- * Set and reset tty into CBREAK or old mode according to argument `state'.
- * It also sets all signal characters (except for ^\) to UNDEF. ^\ is caught.
- */
- void
- raw_mode (state)
- FLAG state;
- {
- #ifdef TERMIO
- static struct termios old_termio;
- struct termios new_termio;
- #ifdef TCGETS
- # define gettermio(fd, iopoi) ioctl (fd, TCGETS, iopoi);
- # ifdef TCSETSW
- # define settermio(fd, iopoi) ioctl (fd, TCSETSW, iopoi);
- # else
- # define settermio(fd, iopoi) ioctl (fd, TCSETS, iopoi);
- # endif
- #else
- # define gettermio(fd, iopoi) tcgetattr (fd, iopoi);
- # ifdef TCSADRAIN
- # define settermio(fd, iopoi) tcsetattr (fd, TCSADRAIN, iopoi);
- # else
- # define settermio(fd, iopoi) tcsetattr (fd, 0, iopoi);
- # endif
- #endif
- #endif /* TERMIO */
-
- #ifdef SGTTY
- static struct sgttyb old_tty;
- struct sgttyb new_tty;
- static int oldlmode;
- int lmode;
- static struct tchars old_tchars;
- static struct ltchars old_ltchars;
- #define NDEF '\377'
- static struct tchars new_tchars = {NDEF, QUITCHAR, NDEF, NDEF, NDEF, NDEF};
- static struct tchars new_QStchars = {NDEF, QUITCHAR, '\021', '\023', NDEF, NDEF};
- static struct ltchars new_ltchars = {NDEF, NDEF, NDEF, NDEF, NDEF, NDEF};
- /* correspondence between the tchars/ltchars characters of the sgtty
- interface and the c_cc characters of the termios interface (codes vary):
- sgtty termio sgtty termio
- t_intrc VINTR t_suspc VSUSP
- t_quitc VQUIT t_dsuspc VDSUSP
- t_startc VSTART t_rprntc VREPRINT
- t_stopc VSTOP t_flushc VDISCARD
- t_eofc VEOF (VMIN) t_werasc VWERASE
- t_brkc VEOL (VTIME) t_lnextc VLNEXT
- */
- #endif /* SGTTY */
-
- if (state == OFF) {
- isscreenmode = FALSE;
- #ifdef CURSES
- endwin ();
- #ifdef vms
- system ("set terminal /ttsync /nopasthru");
- #endif
- #else /* ndef CURSES: */
- end_screen_mode ();
- flush ();
- #endif /* ndef CURSES */
-
- #ifdef TERMIO
- settermio (input_fd, & old_termio);
- #endif
- #ifdef SGTTY
- ioctl (input_fd, TIOCSETP, & old_tty);
- ioctl (input_fd, TIOCSETC, & old_tchars);
- ioctl (input_fd, TIOCSLTC, & old_ltchars);
- ioctl (input_fd, TIOCLSET, & oldlmode);
- #endif
- return;
- }
-
- else /* (state == ON) */ {
- isscreenmode = TRUE;
- #ifdef CURSES
- refresh ();
- #else
- start_screen_mode ();
- flush ();
- #endif
- #ifdef TERMIO
- gettermio (input_fd, & old_termio);
- gettermio (input_fd, & new_termio);
-
- if (controlQS == FALSE)
- new_termio.c_iflag &= ~(ISTRIP|IXON|IXOFF);
- else
- new_termio.c_iflag &= ~(ISTRIP);
- new_termio.c_oflag &= ~OPOST;
- new_termio.c_cflag &= ~(PARENB|CSIZE);
- new_termio.c_cflag |= CS8;
- new_termio.c_lflag &= ~(ICANON|ECHO);
- #define NDEF '\000'
- new_termio.c_cc [VMIN] = 1;
- new_termio.c_cc [VTIME] = 0;
- new_termio.c_cc [VQUIT] = QUITCHAR;
- new_termio.c_cc [VINTR] = NDEF;
- new_termio.c_cc [VSUSP] = NDEF;
- #ifdef VDISCARD
- new_termio.c_cc [VDISCARD] = NDEF;
- #endif
- settermio (input_fd, & new_termio);
- #endif /* TERMIO */
- #ifdef SGTTY
- /* Save old tty settings */
- ioctl (input_fd, TIOCGETP, & old_tty);
- ioctl (input_fd, TIOCGETC, & old_tchars);
- ioctl (input_fd, TIOCGLTC, & old_ltchars);
- ioctl (input_fd, TIOCLGET, & oldlmode);
- /* Set line mode */
- /* If this feature should not be available on some system, RAW must be used
- instead of CBREAK below to enable 8 bit characters on output */
- lmode = oldlmode;
- lmode |= LPASS8; /* enable 8 bit characters on input in CBREAK mode */
- lmode |= LLITOUT; /* enable 8 bit characters on output in CBREAK mode;
- this may not be necessary in newer Unixes, e.g. SUN-OS 4;
- output handling is slightly complicated by LITOUT */
- ioctl (input_fd, TIOCLSET, & lmode);
- /* Set tty to CBREAK (or RAW) mode */
- new_tty = old_tty;
- new_tty.sg_flags &= ~ECHO;
- new_tty.sg_flags |= CBREAK;
- ioctl (input_fd, TIOCSETP, & new_tty);
- /* Unset signal chars */
- if (controlQS == FALSE)
- ioctl (input_fd, TIOCSETC, & new_tchars); /* Only leaves QUITCHAR */
- else
- ioctl (input_fd, TIOCSETC, & new_QStchars); /* Leaves QUITCHAR, ^Q, ^S */
- ioctl (input_fd, TIOCSLTC, & new_ltchars); /* Leaves nothing */
- #endif /* SGTTY */
-
- /* Define signal handlers */
- #ifdef SIGQUIT
- signal (SIGQUIT, catchquit); /* Catch QUITCHAR (^\) */
- #endif
- #ifdef SIGBREAK
- signal (SIGBREAK, catchbreak); /* control-Break (OS/2) */
- #else
- # ifdef msdos
- ctrlbrk (controlbreak); /* completely useless, stupid Turbo-C! */
- # endif
- #endif
- #ifdef SIGINT
- signal (SIGINT, catchint); /* Catch INTR char (^C) */
- #endif
- #ifdef SIGWINCH
- signal (SIGWINCH, catchwinch); /* Catch window size changes */
- #endif
- }
- }
-
- /* ================================================================== *
- * Unix I/O routines *
- * ================================================================== */
-
- #ifdef CURSES
-
- void
- __putchar (c)
- register uchar c;
- { addch (c); }
-
- void
- putstring (str)
- register uchar * str;
- { addstr (str); }
-
- void
- flush ()
- { refresh (); }
-
- FLAG can_add_line = TRUE, can_delete_line = TRUE,
- can_scroll_reverse = TRUE, can_clear_eol = TRUE;
-
- void
- clear_screen ()
- {
- clear ();
- }
- void
- clear_eol ()
- {
- clrtoeol ();
- }
- void
- scroll_forward ()
- {
- scroll (stdscr);
- }
- void
- scroll_reverse ()
- { /* only called if cursor is at top of screen */
- insertln ();
- }
- void
- add_line (y)
- register int y;
- {
- move (y, 0);
- insertln ();
- }
- void
- delete_line (y)
- register int y;
- {
- move (y, 0);
- deleteln ();
- }
- void
- move_cursor (x, y)
- register int x, y;
- {
- move (y, x);
- }
- void
- reverse_on ()
- {
- standout ();
- }
- void
- reverse_off ()
- {
- standend ();
- }
-
- void
- get_term_cap (TERMname)
- char * TERMname;
- {
- #ifdef vms
- system ("set terminal /pasthru /nottsync");
- #endif
- initscr ();
- #ifdef vms
- crmode ();
- #else
- crmode (); /* cbreak (); */
- nonl ();
- #endif
- noecho ();
- scrollok (stdscr, TRUE);
- #ifdef unix
- #ifndef vax
- idlok (stdscr, TRUE);
- #ifndef sun
- typeahead (input_fd);
- #endif
- #endif
- #endif
-
- YMAX = LINES - 1; /* # of lines */
- XMAX = COLS - 1; /* # of columns */
- getwinsize ();
- }
-
- /*------------------------------------------------------------------------*/
- #else /* ndef CURSES: */
-
- void
- __putchar (c)
- register uchar c;
- { writechar (output_fd, (c)); }
-
- void
- putstring (str)
- register uchar * str;
- { (void) writestring (output_fd, (str)); }
-
- void
- flush ()
- { (void) flush_buffer (output_fd); }
-
- #ifdef unix
-
- extern int tgetent ();
- extern char * tgetstr ();
- extern int tgetnum ();
- extern char * tgoto ();
- extern int tputs ();
- #define termputstr(str, aff) (void) tputs (str, aff, (intfunc) __putchar)
-
- /* Storage for the terminal control sequences */
- char *cCL, *cCE, *cSR, *cAL, *cDL, *cCS, *cSC, *cRC,
- *cCM, *cSO, *cSE, *cVS, *cVE, *cTI, *cTE;
- #define aff1 0
- #define affmax YMAX
-
- FLAG can_add_line = FALSE, can_delete_line = FALSE,
- can_scroll_reverse = FALSE, can_clear_eol = FALSE;
-
- void
- clear_screen ()
- {
- termputstr (cCL, affmax);
- }
- void
- clear_eol ()
- {
- if (can_clear_eol == TRUE) termputstr (cCE, aff1);
- }
- void
- scroll_forward ()
- {
- move_cursor (0, YMAX);
- /* putchar ('\n'); */
- termputstr ("\n", affmax);
- }
- void
- scroll_reverse ()
- {
- termputstr (cSR, affmax);
- }
- void
- add_line (y)
- register int y;
- {
- if (cAL) {
- move_cursor (0, y);
- termputstr (cAL, affmax);
- }
- else {
- move_cursor (0, y);
- termputstr (cSC, aff1);
- termputstr (tgoto (cCS, YMAX, y), aff1);
- termputstr (cRC, aff1);
- termputstr (cSR, affmax);
- termputstr (tgoto (cCS, YMAX, 0), aff1);
- termputstr (cRC, aff1);
- }
- }
- void
- delete_line (y)
- register int y;
- {
- if (cDL) {
- move_cursor (0, y);
- termputstr (cDL, affmax);
- }
- else {
- move_cursor (0, y);
- termputstr (cSC, aff1);
- termputstr (tgoto (cCS, YMAX, y), aff1);
- move_cursor (0, YMAX);
- /* putchar ('\n'); */
- termputstr ("\n", affmax);
- termputstr (tgoto (cCS, YMAX, 0), aff1);
- termputstr (cRC, aff1);
- }
- }
- void
- move_cursor (x, y)
- register int x, y;
- {
- termputstr (tgoto (cCM, x, y), aff1);
- }
- void
- reverse_on ()
- {
- termputstr (cSO, aff1);
- }
- void
- reverse_off ()
- {
- termputstr (cSE, aff1);
- }
- void
- start_screen_mode ()
- {
- termputstr (cTI, affmax);
- termputstr (cVS, affmax);
- /* Install correct scrolling region in case terminal is bigger than assumed */
- /* (this effect was observed after window size changes of Sun windows): */
- if (cCS) termputstr (tgoto (cCS, YMAX, 0), aff1);
- }
- void
- end_screen_mode ()
- {
- termputstr (cTE, affmax);
- termputstr (cVE, affmax);
- }
-
- void
- get_term_cap (TERMname)
- char * TERMname;
- {
- #define termbuflen 100
- char entry [1024];
- static char termbuf [termbuflen];
- char * loc = termbuf;
-
- if (tgetent (entry, TERMname) <= 0) {
- panic ("Unknown terminal", NIL_PTR);
- }
-
- YMAX = tgetnum ("li" /*, & loc */) - 1; /* # of lines */
- XMAX = tgetnum ("co" /*, & loc */) - 1; /* # of columns */
- /* getenv ("LINES"), getenv ("COLUMNS") ?! */
- getwinsize ();
-
- cCL = tgetstr ("cl", & loc); /* clear screen */
- cCE = tgetstr ("ce", & loc); /* clear to end of line */
- cSR = tgetstr ("sr", & loc); /* scroll reverse */
- cAL = tgetstr ("al", & loc); /* add line */
- if (!cSR) cSR = cAL;
- cDL = tgetstr ("dl", & loc); /* delete line */
- cCS = tgetstr ("cs", & loc); /* change scrolling region */
- cSC = tgetstr ("sc", & loc); /* save cursor \ needed with vt100 */
- cRC = tgetstr ("rc", & loc); /* restore cursor / for add/delete line */
- cCM = tgetstr ("cm", & loc); /* cursor motion */
- cSO = tgetstr ("so", & loc); /* stand out mode */
- cSE = tgetstr ("se", & loc); /* end " */
- cVS = tgetstr ("vs", & loc); /* visual mode */
- cVE = tgetstr ("ve", & loc); /* end " */
- cTI = tgetstr ("ti", & loc); /* positioning mode */
- cTE = tgetstr ("te", & loc); /* end " */
-
- if (cAL || (cSR && cCS)) can_add_line = TRUE;
- if (cSR) can_scroll_reverse = TRUE;
- if (cDL || cCS) can_delete_line = TRUE;
- if (cCE) can_clear_eol = TRUE;
-
- if (loc > termbuf + termbuflen) {
- panic ("Terminal control strings don't fit", NIL_PTR);
- }
- if (!cCL || !cCM || !cSR || !cCE /* || !cSO || !cSE */ ) {
- panic ("Sorry, no mined on this type of terminal", NIL_PTR);
- }
- }
-
- /*------------------------------------------------------------------------*/
- #endif /* unix */
-
- #ifdef msdos
-
- /*
- * checkwin checks if a screen size change has occurred
- BIOS data:
- 40:4A word video columns
- can also be determined with INT10h, function 0Fh
- 40:84 byte video lines - 1 (EGA/VGA required)
- 40:85 word character height (pixels) (EGA/VGA required)
- can also be determined with INT10h, function 11h/30h
- */
- int
- checkwin ()
- {
- return peek (0x40, 0x4A) != XMAX + 1
- /* the following line requires EGA or VGA: */
- || peekb (0x40, 0x84) != YMAX
- ;
- }
-
- /*
- * getch () reads in a character from keyboard. We seem to need our
- * own low-level input routine since (at least with Turbo-C) the use
- * of getch () from conio.h makes the runtime system switch to normal
- * text mode on startup so that extended text modes could not be used.
- * This is really a very stupid chicane of Turbo-C.
- */
- int wincheck = 1;
- int
- getch ()
- { union REGS Regs;
- int result;
-
- Regs.h.ah = 0x07;
- intdos (& Regs, & Regs);
- result = Regs.h.al;
-
- if (wincheck && checkwin ()) {
- winchg = TRUE;
- /* in MSDOS, RDwin calls getch, so it cannot be called directly here */
- }
-
- return result;
- }
-
- void
- set_video_lines (r)
- /* 0/1/2: 200/350/400 lines */
- int r;
- {
- union REGS Regs;
-
- Regs.h.ah = 0x12;
- Regs.h.bl = 0x30;
- Regs.h.al = r;
-
- int86 (0x10, & Regs, & Regs);
- }
-
- int font_height = 16;
- void
- set_font_height (r)
- /* set font height in character pixels, <= 32 */
- int r;
- {
- #define useintr
- #ifdef useintr
- struct REGPACK Regs;
-
- Regs.r_ax = 0x1130;
- Regs.r_bx = 0;
- intr (0x10, & Regs);
- Regs.r_ax = 0x1110;
- Regs.r_bx = r << 8;
- Regs.r_cx = 256;
- Regs.r_dx = 0;
- /*
- Regs.r_bp = 0;
- Regs.r_es = 0;
- */
- intr (0x10, & Regs);
- #else
- union REGS Regs;
-
- Regs.h.ah = 0x11;
- Regs.h.al = 0x10;
- Regs.h.bh = r;
- font_height = r;
- Regs.h.bl = 0;
- Regs.x.cx = 256;
- Regs.x.dx = 0;
- /* Regs.x.bp = 0; ignored by Turbo-C's int86 function */
- /* Regs.x.es = 0; not in structure but accepted by rotten C */
- int86 (0x10, & Regs, & Regs);
- #endif
- }
-
- void
- set_grafmode_height (r, l)
- /* 0/1/2: font height 8/14/16 ; 1/2/3/n: 14/25/43/n lines */
- int r, l;
- {
- union REGS Regs;
-
- Regs.h.ah = 0x11;
- if (r == 0) Regs.h.al = 0x23;
- else if (r == 1) Regs.h.al = 0x22;
- else Regs.h.al = 0x24;
- if (l <= 0) Regs.h.bl = 1;
- else if (l <= 3) Regs.h.bl = l;
- else {
- Regs.h.bl = 0;
- Regs.h.dl = l;
- }
-
- int86 (0x10, & Regs, & Regs);
- }
-
- void
- set_fontbank (f)
- /* 0..7 */
- int f;
- {
- union REGS Regs;
-
- Regs.h.ah = 0x11;
- Regs.h.al = 0x03;
- Regs.h.bl = (f & 3) * 5 + (f & 4) * 12;
-
- int86 (0x10, & Regs, & Regs);
- }
-
- #ifdef conio
- #include <conio.h>
-
- FLAG can_add_line = TRUE, can_delete_line = TRUE,
- can_scroll_reverse = TRUE, can_clear_eol = TRUE;
-
- void
- clear_screen ()
- { clrscr (); }
- void
- clear_eol ()
- { clreol (); }
- void
- scroll_forward ()
- {
- move_cursor (0, YMAX);
- putchar ('\n');
- }
- void
- scroll_reverse ()
- { /* only called if cursor is at top of screen */
- insline ();
- }
- void
- add_line (y)
- register int y;
- {
- move_cursor (0, y);
- insline ();
- }
- void
- delete_line (y)
- register int y;
- {
- move_cursor (0, y);
- delline ();
- }
- void
- move_cursor (x, y)
- {
- gotoxy (x + 1, y + 1);
- }
- void
- reverse_on ()
- { highvideo ();
- }
- void
- reverse_off ()
- { normvideo ();
- }
- void
- start_screen_mode ()
- {}
- void
- end_screen_mode ()
- {}
-
- void
- get_term ()
- {
- getwinsize ();
- }
-
- void
- getwinsize ()
- {
- /* this has to be extended to request the current screen size */
- struct text_info scrinfo;
-
- gettextinfo (& scrinfo);
- /* This seems to be a junk procedure since no other information than
- 25 * 80 comes out in 50 lines mode */
- YMAX = scrinfo.screenheight - 1;
- XMAX = scrinfo.screenwidth - 1;
- }
-
- #else /* ndef conio - use ANSI driver: */
-
- /* adjust the following values to the capabilities of your ANSI driver: */
- FLAG can_add_line = TRUE, can_delete_line = TRUE,
- can_scroll_reverse = TRUE, can_clear_eol = TRUE;
-
- char CUP1 [] = "\033[1;1H";
- char CUD1 [] = "\033[B";
- char CUF1 [] = "\033[C";
- char DSR [] = "\033[6n";
- char ED2 [] = "\033[2J";
- char EL [] = "\033[K";
- char IL1 [] = "\033[L";
- char DL1 [] = "\033[M";
-
- void
- clear_screen ()
- { putstring (ED2); }
- void
- clear_eol ()
- {
- if (can_clear_eol == TRUE) putstring (EL);
- }
- void
- scroll_forward ()
- {
- move_cursor (0, YMAX);
- putchar ('\n');
- }
- void
- scroll_reverse ()
- { /* only called if cursor is at top of screen */
- putstring (IL1);
- }
- void
- add_line (y)
- register int y;
- {
- move_cursor (0, y);
- putstring (IL1);
- }
- void
- delete_line (y)
- register int y;
- {
- move_cursor (0, y);
- putstring (DL1);
- }
- void
- move_cursor (x, y)
- register int x, y;
- { static char s [11];
- build_string (s, "\033[%d;%dH", y + 1, x + 1);
- putstring (s);
- }
- char reverse_on_str [30] = "\033[7m"; /* inverse mode */
- char reverse_off_str [30] = "\033[27m"; /* inverse off */
- void
- reverse_on ()
- { putstring (reverse_on_str); /* 1m | 7m | 7m | 7;2m */
- }
- void
- reverse_off ()
- { putstring (reverse_off_str); /* m | 0m | 0m 1m | m */
- }
- void
- start_screen_mode ()
- {}
- void
- end_screen_mode ()
- {}
-
- FLAG noCPR = FALSE;
-
- int
- getANSIpos ()
- /* returns FALSE if indicated position is upper left corner */
- /* also leaves position in XMAX+1, YMAX+1 */
- /* Checks characters input against ANSI CPR (cursor position report)
- sequence. If it does not comply, sets noCPR flag, does not check again
- and reports as if cursor had been moved. By this trick, we implement
- the following auxiliary behaviour: If an ANSI driver cannot deliver
- cursor reports, mined may be stuffed the screen size as its first input,
- at the positions of an ANSI CPR sequence but embedded in different
- characters, e.g. xx25x80xx */
- {
- if (noCPR == TRUE) return 1;
- wincheck = 0; /* prevent recursive calls of checkwin and getANSIpos */
- putstring (DSR);
- flush ();
- if (readchar () != '\033') noCPR = TRUE;
- if (readchar () != '[') noCPR = TRUE;
- if (get_digits (& YMAX) != ';') noCPR = TRUE;
- if (get_digits (& XMAX) != 'R') noCPR = TRUE;
- (void) readchar (); /* MSDOS ANSI drivers send a final return */
- YMAX = YMAX - 1; XMAX = XMAX - 1;
- wincheck = 1;
- return YMAX != 0 || XMAX != 0;
- }
-
- int
- failANSI (check)
- /* returns FALSE if control string does not change screen position */
- char * check;
- {
- putstring (CUP1);
- putstring (check);
- return getANSIpos ();
- }
-
- void
- get_term ()
- {
- char * colstr = unnull (getenv ("MINEDCOL"));
- char * colrev = colstr;
- while (* colrev != '\0' && * colrev != ' ') colrev ++;
- if (* colrev == ' ') {* colrev = '\0'; colrev ++;}
-
- /* first do some harmless checks to set noCPR if simple ANSI driver */
- /* if (failANSI (EL)) can_clear_eol = FALSE; probably every driver can do this */
- if (failANSI (DL1)) can_delete_line = FALSE;
- if (failANSI (IL1)) {
- can_add_line = FALSE;
- can_scroll_reverse = FALSE;
- }
-
- /* heuristics: if driver cannot delete line we assume if can neither set
- extended attributes like our default inverse and inverse off,
- so change the default */
- if (can_delete_line == FALSE) {
- build_string (reverse_off_str, "\033[32;40m");
- build_string (reverse_on_str, "\033[30;42m");
- }
-
- /* if MINEDCOL set, use it for display attributes instead of defaults */
- if (* colstr != '\0') build_string (reverse_off_str, "\033[%sm", colstr);
- if (* colrev != '\0') build_string (reverse_on_str, "\033[%sm", colrev);
-
- /* if cursor reports are available, check display attribute strings */
- if (noCPR == FALSE) {
- if (failANSI (reverse_on_str)) panic ("Invalid control sequence for exposed display", NIL_PTR);
- if (failANSI (reverse_off_str)) panic ("Invalid control sequence for normal display", NIL_PTR);
- }
-
- getwinsize ();
- }
-
- void
- getwinsize ()
- {
- #define stepcur 9
- int oldx = -1; int oldy = -1;
- int i;
- if (noCPR == FALSE) {
- putstring (CUP1);
- XMAX = 0; YMAX = 0;
- do {
- for (i = 0; i < stepcur; i ++) {
- if (oldx < XMAX) putstring (CUF1);
- if (oldy < YMAX) putstring (CUD1);
- }
- oldx = XMAX + (stepcur - 1);
- oldy = YMAX + (stepcur - 1);
- (void) getANSIpos ();
- } while (oldx < XMAX || oldy < YMAX);
- }
- if (getenv ("LINES")) {make_number (& YMAX, getenv ("LINES")); YMAX --;}
- if (getenv ("COLUMNS")) {make_number (& XMAX, getenv ("COLUMNS")); XMAX --;}
- if (getenv ("NOCLEAREOL")) can_clear_eol = FALSE; /* for debugging */
- /* move_cursor (999, 999); */
- /* (void) getANSIpos (); */
- }
-
- #endif /* ndef conio */
- #endif /* def msdos */
-
- /****************************************************************************
- * screen mode setting functions, alternatively by MSDOS BIOS calls or
- * ANSI sequences
- */
-
- int textmode_height = 2;
-
- #ifdef msdos
-
- void
- set_screen_mode (m)
- int m;
- {
- union REGS Regs;
-
- if (m >= 0) {
- Regs.h.ah = 0x00;
- Regs.h.al = m;
- int86 (0x10, & Regs, & Regs);
- }
- }
-
- void
- set_textmode_height (r)
- /* 0/1/2: font height 8/14/16 */
- int r;
- {
- union REGS Regs;
-
- Regs.h.ah = 0x11;
- Regs.h.bl = 0;
- textmode_height = r;
- if (r == 0) Regs.h.al = 0x12;
- else if (r == 1) Regs.h.al = 0x11;
- else Regs.h.al = 0x14;
-
- int86 (0x10, & Regs, & Regs);
- }
-
- #else /* ndef msdos - use ANSI driver: */
-
- int screen_mode = 3 /* just an assumption, cannot be determined */;
-
- void
- set_screen_mode (m)
- int m;
- {
- char resize_str [8];
-
- if (m >= 0) {
- if (m != 50 && m != 43) screen_mode = m;
- build_string (resize_str, "\033[=%dh", m);
- putstring (resize_str);
- }
- }
-
- void
- set_textmode_height (r)
- /* 0/1/2: font height 8/14/16 */
- int r;
- {
- textmode_height = r;
- if (r == 0) set_screen_mode (50);
- else if (r == 1) set_screen_mode (43);
- else set_screen_mode (screen_mode);
- }
-
- #endif
-
- void
- switch_textmode_height (cycle)
- /* TRUE: cycle through font heights 8/14/16
- FALSE: switch between font heights 8/16 */
- FLAG cycle;
- {
- if (textmode_height >= 2) set_textmode_height (0);
- else if (cycle == TRUE) set_textmode_height (textmode_height + 1);
- else set_textmode_height (2);
- }
-
- extern
- struct {
- int mode, cols, lins;
- } modetab [] /* in minedmp.c together with other configurable stuff */;
-
- void
- resize_screen (sb, keep_columns)
- FLAG sb, keep_columns;
- {
- /* char resize_str [8]; */
- int totalchars = (XMAX + 1) * (YMAX + 1);
- int newtotal = 0;
- int curtotal;
- int newmode = -1;
- int i;
-
- if (keep_columns == TRUE && ((sb == SMALLER && textmode_height > 0)
- || (sb == BIGGER && textmode_height < 2)))
- {
- if (sb == SMALLER)
- set_textmode_height (textmode_height - 1);
- else set_textmode_height (textmode_height + 1);
- }
- else
- {
- i = 0;
- while (modetab [i].mode >= 0) {
- curtotal = modetab [i].cols * modetab [i].lins;
- if (((sb == SMALLER && curtotal < totalchars && curtotal > newtotal) ||
- (sb == BIGGER && curtotal > totalchars && (newtotal == 0 || curtotal < newtotal)))
- && (keep_columns == FALSE || modetab [i].cols == XMAX + 1))
- { newtotal = curtotal;
- newmode = modetab [i].mode;
- }
- i ++;
- }
- if (newmode >= 0) {
- set_screen_mode (newmode);
- if (keep_columns == TRUE)
- if (sb == BIGGER)
- set_textmode_height (0);
- else set_textmode_height (2);
- }
- }
- }
-
- #endif /* ndef CURSES */
-
- /*------------------------------------------------------------------------*/
-
- /*
- * Read a character from the operating system and handle interrupts.
- * Concerning problems due to the interference of read operations and
- * incoming signals (QUIT, WINCH) see the comments at readchar ().
- */
- int
- strange (err)
- char * err;
- {
- ring_bell ();
- error ("Read interrupted: ", err);
- sleep (1);
- ring_bell ();
- return QUITCHAR;
- }
-
- /*
- * Is a character available within msec milliseconds from file no fid?
- */
- int
- inputreadyafter (fid, msec)
- int fid;
- int msec;
- {
- #ifdef selectread
- int readfds;
- static struct timeval timeoutstru = {0, 0};
- register int nfds;
-
- readfds = 1 << fid;
- timeoutstru.tv_usec = 1000 * msec;
- nfds = select (fid + 1, & readfds, 0, 0, & timeoutstru);
- return nfds;
- #else
- if (msec < 500)
- return 1;
- else return fid - fid;
- #endif
- }
-
- /*
- * Read a char from operating system, handle interrupts if possible,
- * handle window size changes if possible.
- */
- #ifdef selectread
- int
- __readchar ()
- {
- uchar c;
- register int n;
- int readfds, exceptfds;
-
- do {
- if (winchg == TRUE) RDwin ();
- readfds = 1 << input_fd;
- exceptfds = readfds;
- select (input_fd + 1, & readfds, 0, & exceptfds, 0);
- if (exceptfds) {
- if (quit == TRUE) return QUITCHAR;
- else if (winchg == TRUE) ;
- else if (intr_char == TRUE) {intr_char = FALSE; return '\003';}
- else return strange ("exception");
- }
- else
- #ifdef _getch_
- return getch ();
- #else
- {
- if ((n = read (input_fd, & c, 1)) == 1) return c;
- else if ((n == 0) || (geterrno () != EINTR))
- panicio ("Error during character input", serror ());
- else return strange (serror ());
- }
- #endif
- } while (TRUE);
- }
- #else
- int
- __readchar ()
- {
- uchar c;
-
- #ifdef _getch_
- c = getch ();
- if (intr_char == TRUE) {intr_char = FALSE; c = '\003';}
- #else
- if (read (input_fd, & c, 1) != 1 && quit == FALSE) {
- if (geterrno () == EINTR) return __readchar ();
- else panicio ("Error during character input", serror ());
- }
- #endif
- if (quit == TRUE) c = QUITCHAR;
- return c;
- }
- #endif
-
- /*------------------------------------------------------------------------*/
-
- #ifdef vms
-
- void
- get_term ()
- {
- get_term_cap (NIL_PTR);
- }
-
- void
- getwinsize ()
- {
- /* Can this be determined on VMS? Any advise by someone? */
- }
-
- #endif /* vms */
-
- #ifdef unix
-
- /*
- * Get current window size
- */
- void
- getwinsize ()
- {
- #ifdef TIOCGWINSZ
- struct winsize winsiz;
-
- ioctl (output_fd, TIOCGWINSZ, & winsiz);
- if (winsiz.ws_row != 0) YMAX = winsiz.ws_row - 1;
- if (winsiz.ws_col != 0) XMAX = winsiz.ws_col - 1;
- #else
- #ifdef TIOCGSIZE
- struct ttysize ttysiz;
-
- ioctl (output_fd, TIOCGSIZE, & ttysiz);
- if (ttysiz.ts_lines != 0) YMAX = ttysiz.ts_lines - 1;
- if (ttysiz.ts_cols != 0) XMAX = ttysiz.ts_cols - 1;
- #else
- #ifdef WIOCGETD
- struct uwdata uwdat;
-
- ioctl (output_fd, WIOCGETD, & uwdat);
- if (uwdat.uw_height > 0) YMAX = uwdat.uw_height / uwdat.uw_vs - 1;
- if (uwdat.uw_width > 0) XMAX = uwdat.uw_width / uwdat.uw_hs - 1;
- #else
- /* Who can tell me how to do this on different systems? */
- #endif
- #endif
- #endif
- }
-
- /*
- * Get terminal information
- */
- void
- get_term ()
- {
- char * TERMname = getenv ("TERM");
-
- if (TERMname == NIL_PTR)
- panic ("Terminal not specified", NIL_PTR);
-
- get_term_cap (TERMname);
-
- /* build_string (text_buffer, "Terminal is %s, %d * %d.\n", TERMname, YMAX+1, XMAX+1);
- putstring (text_buffer); */
- }
-
- #endif /* unix */
-
- /* ================================================================== *
- * End *
- * ================================================================== */
-